/**
 * 
 */
package pl.kane.autokomp.livegenerator;

import java.awt.AWTException;
import java.awt.GraphicsDevice;
import java.awt.Robot;
import java.awt.event.KeyEvent;
import java.text.DateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import pl.kane.autokomp.applications.MainFrame;
import pl.kane.autokomp.livegenerator.dto.KeyData;

/**
 * @author Lukasz Wator
 *
 */
public class AutoKompRobot extends Robot {
	
	final MainFrame mainFrame = MainFrame.getInstance() ;

	public Map keysMap;
	public AutoKompRobot() throws AWTException {
		super();
		keysMap = new HashMap();
		keysMap.put("a", new KeyData (KeyEvent.VK_A));
		keysMap.put("A", new KeyData (KeyEvent.VK_A,true));
		keysMap.put("b", new KeyData (KeyEvent.VK_B));
		keysMap.put("B", new KeyData (KeyEvent.VK_B,true));
		keysMap.put("c", new KeyData (KeyEvent.VK_C));
		keysMap.put("C", new KeyData (KeyEvent.VK_C,true));
		keysMap.put("d", new KeyData (KeyEvent.VK_D));
		keysMap.put("D", new KeyData (KeyEvent.VK_D,true));
		keysMap.put("e", new KeyData (KeyEvent.VK_E));
		keysMap.put("E", new KeyData (KeyEvent.VK_E,true));
		keysMap.put("f", new KeyData (KeyEvent.VK_F));
		keysMap.put("F", new KeyData (KeyEvent.VK_F,true));
		keysMap.put("g", new KeyData (KeyEvent.VK_G));
		keysMap.put("G", new KeyData (KeyEvent.VK_G,true));
		keysMap.put("h", new KeyData (KeyEvent.VK_H));
		keysMap.put("H", new KeyData (KeyEvent.VK_H,true));
		keysMap.put("i", new KeyData (KeyEvent.VK_I));
		keysMap.put("I", new KeyData (KeyEvent.VK_I,true));
		keysMap.put("j", new KeyData (KeyEvent.VK_J));
		keysMap.put("J", new KeyData (KeyEvent.VK_J,true));
		keysMap.put("k", new KeyData (KeyEvent.VK_K));
		keysMap.put("K", new KeyData (KeyEvent.VK_K,true));
		keysMap.put("l", new KeyData (KeyEvent.VK_L));
		keysMap.put("L", new KeyData (KeyEvent.VK_L,true));
		keysMap.put("m", new KeyData (KeyEvent.VK_M));
		keysMap.put("M", new KeyData (KeyEvent.VK_M,true));
		keysMap.put("n", new KeyData (KeyEvent.VK_N));
		keysMap.put("N", new KeyData (KeyEvent.VK_N,true));
		keysMap.put("o", new KeyData (KeyEvent.VK_O));
		keysMap.put("O", new KeyData (KeyEvent.VK_O,true));
		keysMap.put("p", new KeyData (KeyEvent.VK_P));
		keysMap.put("P", new KeyData (KeyEvent.VK_P,true));
		keysMap.put("q", new KeyData (KeyEvent.VK_Q));
		keysMap.put("Q", new KeyData (KeyEvent.VK_Q,true));
		keysMap.put("r", new KeyData (KeyEvent.VK_R));
		keysMap.put("R", new KeyData (KeyEvent.VK_R,true));
		keysMap.put("s", new KeyData (KeyEvent.VK_S));
		keysMap.put("S", new KeyData (KeyEvent.VK_S,true));
		keysMap.put("t", new KeyData (KeyEvent.VK_T));
		keysMap.put("T", new KeyData (KeyEvent.VK_T,true));
		keysMap.put("u", new KeyData (KeyEvent.VK_U));
		keysMap.put("U", new KeyData (KeyEvent.VK_U,true));
		keysMap.put("v", new KeyData (KeyEvent.VK_V));
		keysMap.put("V", new KeyData (KeyEvent.VK_V,true));
		keysMap.put("w", new KeyData (KeyEvent.VK_W));
		keysMap.put("W", new KeyData (KeyEvent.VK_W,true));
		keysMap.put("x", new KeyData (KeyEvent.VK_X));
		keysMap.put("X", new KeyData (KeyEvent.VK_X,true));
		keysMap.put("y", new KeyData (KeyEvent.VK_Y));
		keysMap.put("Y", new KeyData (KeyEvent.VK_Y,true));
		keysMap.put("z", new KeyData (KeyEvent.VK_Z));
		keysMap.put("Z", new KeyData (KeyEvent.VK_Z,true));
		keysMap.put("1", new KeyData (KeyEvent.VK_1));
		keysMap.put("2", new KeyData (KeyEvent.VK_2));
		keysMap.put("3", new KeyData (KeyEvent.VK_3));
		keysMap.put("4", new KeyData (KeyEvent.VK_4));
		keysMap.put("5", new KeyData (KeyEvent.VK_5));
		keysMap.put("6", new KeyData (KeyEvent.VK_6));
		keysMap.put("7", new KeyData (KeyEvent.VK_7));
		keysMap.put("8", new KeyData (KeyEvent.VK_8));
		keysMap.put("9", new KeyData (KeyEvent.VK_9));
		keysMap.put("0", new KeyData (KeyEvent.VK_0));
		keysMap.put("!", new KeyData (KeyEvent.VK_EXCLAMATION_MARK));
		keysMap.put("@", new KeyData (KeyEvent.VK_AT));
		keysMap.put("#", new KeyData (KeyEvent.VK_NUMBER_SIGN));
		keysMap.put("$", new KeyData (KeyEvent.VK_DOLLAR));
		keysMap.put("%", new KeyData (KeyEvent.VK_5,true)); //nie ma znaku %!!
		keysMap.put("^", new KeyData (KeyEvent.VK_CIRCUMFLEX));
		keysMap.put("&", new KeyData (KeyEvent.VK_AMPERSAND));
		keysMap.put("*", new KeyData (KeyEvent.VK_MULTIPLY));
		keysMap.put("(", new KeyData (KeyEvent.VK_LEFT_PARENTHESIS));
		keysMap.put(")", new KeyData (KeyEvent.VK_RIGHT_PARENTHESIS));
		keysMap.put("_", new KeyData (KeyEvent.VK_UNDERSCORE));
		keysMap.put("=", new KeyData (KeyEvent.VK_EQUALS));
		keysMap.put("+", new KeyData (KeyEvent.VK_PLUS));
		keysMap.put("-", new KeyData (KeyEvent.VK_MINUS));
		keysMap.put(":", new KeyData (KeyEvent.VK_COLON));
		keysMap.put(",", new KeyData (KeyEvent.VK_COMMA));
		keysMap.put(".", new KeyData (KeyEvent.VK_PERIOD));
		keysMap.put("/", new KeyData (KeyEvent.VK_SLASH));
		keysMap.put("\\", new KeyData (KeyEvent.VK_BACK_SLASH));
		keysMap.put("'", new KeyData (KeyEvent.VK_ASTERISK));
		keysMap.put("\"", new KeyData (KeyEvent.VK_QUOTEDBL));
		keysMap.put("<", new KeyData (KeyEvent.VK_LESS));
		keysMap.put(">", new KeyData (KeyEvent.VK_GREATER));
		keysMap.put("]", new KeyData (KeyEvent.VK_BRACELEFT));
		keysMap.put("[", new KeyData (KeyEvent.VK_BRACERIGHT));
		keysMap.put(" ", new KeyData (KeyEvent.VK_SPACE));
	    
	    
		
		keysMap.put("ENTER", new KeyData (KeyEvent.VK_ENTER));
		keysMap.put("ESC", new KeyData (KeyEvent.VK_ESCAPE));
		keysMap.put("BACKSPACE", new KeyData (KeyEvent.VK_BACK_SPACE));
		keysMap.put("DELETE", new KeyData (KeyEvent.VK_DELETE));
		keysMap.put("TAB", new KeyData (KeyEvent.VK_TAB));
		keysMap.put("WINDOWS", new KeyData (KeyEvent.VK_WINDOWS));
		keysMap.put("SPACE", new KeyData (KeyEvent.VK_SPACE));
		keysMap.put("LEFT", new KeyData (KeyEvent.VK_LEFT));
		keysMap.put("RIGHT", new KeyData (KeyEvent.VK_RIGHT));
		keysMap.put("UP", new KeyData (KeyEvent.VK_UP));
		keysMap.put("DOWN", new KeyData (KeyEvent.VK_DOWN));

		keysMap.put("SHIFT", new KeyData (KeyEvent.VK_SHIFT));
		keysMap.put("CONTROL", new KeyData (KeyEvent.VK_CONTROL));
		keysMap.put("ALT", new KeyData (KeyEvent.VK_ALT));
		keysMap.put("CAPSLOCK", new KeyData (KeyEvent.VK_CAPS_LOCK));
		keysMap.put("PAGEUP", new KeyData (KeyEvent.VK_PAGE_UP));
		keysMap.put("PAGEDOWN", new KeyData (KeyEvent.VK_PAGE_DOWN));
		keysMap.put("END", new KeyData (KeyEvent.VK_END));
		keysMap.put("HOME", new KeyData (KeyEvent.VK_HOME));
		
		keysMap.put("F1", new KeyData (KeyEvent.VK_F1));
		keysMap.put("F2", new KeyData (KeyEvent.VK_F2));
		keysMap.put("F3", new KeyData (KeyEvent.VK_F3));
		keysMap.put("F4", new KeyData (KeyEvent.VK_F4));
		keysMap.put("F5", new KeyData (KeyEvent.VK_F5));
		keysMap.put("F6", new KeyData (KeyEvent.VK_F6));
		keysMap.put("F7", new KeyData (KeyEvent.VK_F7));
		keysMap.put("F8", new KeyData (KeyEvent.VK_F8));
		keysMap.put("F9", new KeyData (KeyEvent.VK_F9));
		keysMap.put("F10", new KeyData (KeyEvent.VK_F10));
		keysMap.put("F11", new KeyData (KeyEvent.VK_F11));
		keysMap.put("F12", new KeyData (KeyEvent.VK_F12));
		
		
		
		this.setAutoDelay(50);
	

	 
	
	 
	}

	public AutoKompRobot(GraphicsDevice screen) throws AWTException {
		super(screen);
		
	}
	
	public void write(String text) throws AWTException {
		logToConsole("Start writing text: "+text );
		for (int i=0;i<text.length();i++) {
			press(text.substring(i,i+1));
			this.delay(this.getAutoDelay());
		}
	}
	
	public synchronized void delay(int ms) {
		//logToConsole("Start delay for: " +ms+" ms");
		super.delay(ms);
	}

	public synchronized void mouseMove(int x, int y) {
		logToConsole("Mouse moved to: ("+x+","+y+")");
		super.mouseMove(x, y);
	}

	public synchronized void mousePress(int buttons) {
		logToConsole("Mouse pressed");
		super.mousePress(buttons);
	}

	public synchronized void mouseRelease(int buttons) {
		logToConsole("Mouse released");
		super.mouseRelease(buttons);
	}
	
	public void hold(String key) throws AWTException {
		KeyData keyData = ((KeyData)keysMap.get(key));
		if (keyData == null)
			throw new AWTException("Unknow character " + key);
		if (keyData.isUpperCase()) 
			this.keyPress(KeyEvent.VK_SHIFT);
		this.keyPress(keyData.getKey());
		if (keyData.isUpperCase()) 
			this.keyRelease(KeyEvent.VK_SHIFT);
	}
	
	public void release(String key) throws AWTException {
		KeyData keyData = ((KeyData)keysMap.get(key));
		if (keyData == null)
			throw new AWTException("Unknow character " + key);
		if (keyData.isUpperCase()) 
			this.keyPress(KeyEvent.VK_SHIFT);
		this.keyRelease(keyData.getKey());
		if (keyData.isUpperCase()) 
			this.keyRelease(KeyEvent.VK_SHIFT);
	}

	public void press(String key) throws AWTException {
		KeyData keyData = ((KeyData)keysMap.get(key));
		if (keyData == null)
			throw new AWTException("Unknow character " + key);
		if (keyData.isUpperCase()) 
			this.keyPress(KeyEvent.VK_SHIFT);
		this.keyPress(keyData.getKey());
		this.delay(this.getAutoDelay());
		this.keyRelease(keyData.getKey());
		if (keyData.isUpperCase()) 
			this.keyRelease(KeyEvent.VK_SHIFT);
	}
	
	public void logToConsole(String text) {
		mainFrame.hideWindow();
		Date now = new Date();
		mainFrame.addToConsole(DateFormat.getTimeInstance().format(now)+" "+text+"\n");
	}
}
